package app.itgungnir.compose.wan.theme

import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Typography
import androidx.compose.material.darkColors
import androidx.compose.material.lightColors
import androidx.compose.runtime.*
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontFamily
import app.itgungnir.compose.wan.WanApp
import app.itgungnir.compose.wan.utils.LocalDataStore
import app.itgungnir.compose.wan.utils.dataStore
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.map

private var currentPalette by mutableStateOf<Palette>(RedPalette)
private var currentTypography by mutableStateOf(DefaultTypography)

@Composable
fun WanComposeTheme(content: @Composable () -> Unit) {
    val systemDark = WanApp.instance.dataStore.data.map { it.darkModeExtendSystem }.collectAsState(initial = true)
    val darkEnabled = WanApp.instance.dataStore.data.map { it.darkModeEnabled }.collectAsState(initial = false)
    MaterialTheme(
        colors = getThemeColors(isSystemInDarkTheme() && systemDark.value || darkEnabled.value),
        typography = getTypography(),
        shapes = MaterialTheme.shapes,
        content = content
    )
    // State observation
    LaunchedEffect(key1 = Unit) {
        WanApp.instance.dataStore.data.map { it.themePaletteIndex }.collect {
            switchColorPalette(it)
        }
    }
    LaunchedEffect(key1 = Unit) {
        WanApp.instance.dataStore.data.map { it.fontTypographyIndex }.collect {
            switchFontTypography(it)
        }
    }
}

@Composable
fun WanComposePreviewTheme(content: @Composable () -> Unit) {
    MaterialTheme(
        colors = getThemeColors(isSystemInDarkTheme()),
        typography = getTypography(),
        shapes = MaterialTheme.shapes,
        content = content
    )
}

suspend fun switchColorPalette(colorPaletteIndex: Int) {
    currentPalette = when (colorPaletteIndex) {
        1 -> PinkPalette
        2 -> PurplePalette
        3 -> BluePalette
        4 -> CyanPalette
        5 -> TealPalette
        6 -> GreenPalette
        7 -> LimePalette
        8 -> OrangePalette
        9 -> BrownPalette
        else -> RedPalette
    }
    LocalDataStore.updateLocalData {
        it.themePaletteIndex = colorPaletteIndex
    }
}

suspend fun switchFontTypography(fontTypographyIndex: Int) {
    currentTypography = when (fontTypographyIndex) {
        1 -> MediumTypography
        2 -> BiggerTypography
        3 -> LargeTypography
        4 -> HugeTypography
        else -> DefaultTypography
    }
    LocalDataStore.updateLocalData {
        it.fontTypographyIndex = fontTypographyIndex
    }
}

private fun getThemeColors(isSystemInDarkTheme: Boolean) = when (isSystemInDarkTheme) {
    true -> darkColors(
        primary = currentPalette.darkPrimaryColor,
        primaryVariant = currentPalette.primaryVariantColor,
        secondary = currentPalette.darkSecondaryColor,
        secondaryVariant = currentPalette.darkSecondaryColor,
        background = Color.Black,
        surface = Color(0xFF1F1F1F),
        error = Color(0xFFCF6679),
        onPrimary = Color.Black,
        onSecondary = Color.Black,
        onBackground = Color.White,
        onSurface = Color.White,
        onError = Color.Black
    )
    else -> lightColors(
        primary = currentPalette.lightPrimaryColor,
        primaryVariant = currentPalette.primaryVariantColor,
        secondary = currentPalette.lightSecondaryColor,
        secondaryVariant = currentPalette.lightSecondaryColor,
        background = Color.White,
        surface = Color(0xFFF0F0F0),
        error = Color(0xFFB00020),
        onPrimary = Color.White,
        onSecondary = Color.Black,
        onBackground = Color.Black,
        onSurface = Color.Black,
        onError = Color.White
    )
}

private fun getTypography() = Typography(
    defaultFontFamily = FontFamily.Default,
    h1 = currentTypography.h1,
    h2 = currentTypography.h2,
    h3 = currentTypography.h3,
    h4 = currentTypography.h4,
    h5 = currentTypography.h5,
    h6 = currentTypography.h6,
    subtitle1 = currentTypography.subtitle1,
    subtitle2 = currentTypography.subtitle2,
    body1 = currentTypography.body1,
    body2 = currentTypography.body2,
    button = currentTypography.button,
    caption = currentTypography.caption,
    overline = currentTypography.overline
)
